package com.ec.common.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ec.common.utils.StringUtils;

/**
 * 防止XSS攻击的过滤器
 * 这表示该类是一个过滤器，用于处理 Servlet请求和响应
 * 根据请求的 URL 和方法来决定是否要对请求进行特殊处理（可能是进行 XSS 过滤），
 * 并在需要时创建一个包装后的请求对象。具体的功能和行为将取决于 XssHttpServletRequestWrapper 类的实现。
 * 同时，它还可以根据配置中的排除列表来跳过某些 URL 的处理。
 * @author ec
 */
public class XssFilter implements Filter {

    /**
     * 存储要排除路径url的列表
     */
    public List<String> excludes = new ArrayList<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 从配置中获取名为 excludes 的初始化参数
        String tempExcludes = filterConfig.getInitParameter("excludes");
        // 并将其分割成字符串数组，然后添加到 excludes 列表中
        if (StringUtils.isNotEmpty(tempExcludes)) {
            String[] url = tempExcludes.split(",");
            for (int i = 0; url != null && i < url.length; i++) {
                excludes.add(url[i]);
            }
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // public interface HttpServletRequest extends ServletRequest
        // public interface HttpServletResponse extends ServletResponse
        // 强制类型转换  都是继承它 属于子类(interface)
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        // 检查是否处理了排除的 URL。如果是，直接调用过滤器链中的下一个过滤器或目标 Servlet
        if (handleExcludeURL(req, resp)) {
            chain.doFilter(request, response);
            return;
        }
        // 否则，创建一个新的 XssHttpServletRequestWrapper 对象，并通过该对象传递请求给过滤器链。
        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
        chain.doFilter(xssRequest, response);
    }


    // 私有方法
    private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
        String url = request.getServletPath();
        String method = request.getMethod();
        // 如果方法是 GET 或 DELETE，或者方法为空，返回 true 表示处理了排除的 UR
        if (method == null || method.matches("GET") || method.matches("DELETE")) {
            return true;
        }
        // 通过 StringUtils.matches(url, excludes) 检查 URL 是否匹配排除列表中的任何项
        return StringUtils.matches(url, excludes);
    }


    @Override
    public void destroy() {

    }
}
